# -*-coding:utf-8 -*-
from django.db import models
from django.conf import settings
from datetime import datetime
from easy_thumbnails.fields import ThumbnailerImageField
from urllib.parse import urlparse
from django.db.models.signals import m2m_changed, post_save
from django.dispatch import receiver
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import json
NOTIFY_BROKER = getattr(settings, 'NOTIFY_BROKER', None)
# Create your models here.


def read_count_add(obj):
    if hasattr(obj, "read_count"):
        post_save.disconnect(auto_push_change_info, sender=obj.__class__)
        obj.read_count += 1
        obj.save()
        post_save.connect(auto_push_change_info, sender=obj.__class__)
    return obj

class ContentManager(models.Manager):
    def published(self):
        qs = self.get_queryset()
        return qs.filter(published=True, auditstatus='Y', publishdate__lt=datetime.now())

    def foucs(self):
        qs = self.get_queryset()
        return qs.filter(published=True, auditstatus='Y', publishdate__lt=datetime.now()).order_by("-read_count")[:5]

    def latest(self, n=5):
        qs = self.get_queryset()
        return qs.filter(published=True, auditstatus='Y', publishdate__lt=datetime.now()).order_by("-publishdate")[:n]

    def category(self, category=None):
        qs = self.get_queryset()
        return qs.filter(published=True, auditstatus='Y', publishdate__lt=datetime.now(), category=category)

    def audits(self):
        qs = self.get_queryset()
        return qs.filter(auditstatus='Y').order_by("-createdat")


class Content(models.Model):
    objects = ContentManager()

    CAT_NEWS = u'NEWS'  # 新闻类
    CAT_DYNAMIC = u'DYNAMIC'  # 动态类
    CAT_OFFICE = u'OFFICE'  # 行政文件
    CAT_NOTICE = u'NOTICE'  # 通知
    CAT_NOTIFY = u'NOTIFY'  # 公告
    CAT_VIDEO = u'VIDEO'  # 视频
    CAT_PICTURE = u'PICTURE'  # 照片
    CAT_3P = u'3P'  # 三方内容
    CAT_OTHER = u'OTHER'  # 其他分类

    AUDIT_YES = "Y"
    AUDIT_NO = "N"

    AUDITS = ((AUDIT_YES, u'同意'), (AUDIT_NO, u'不同意'))

    CATEGORYS = ((CAT_NEWS, u'新闻资讯类'), (CAT_DYNAMIC, u'动态类'), (CAT_OFFICE, u'行政公文'), (CAT_NOTICE,
                                                                                      u'通知'),  (CAT_NOTIFY, u'公告'),  (CAT_VIDEO, u'视频'), (CAT_PICTURE, u'图像'), (CAT_3P, '三方内容'), (CAT_OTHER, u'其他'),)
    # default_pic = models.ImageField(u'默认图片', upload_to='core/content/%Y/%m/',
    #                                 blank=True, null=True, help_text=u'推荐到首页的时候显示在幻灯片中间的照片')
    category = models.CharField(u'板块', max_length=64, choices=CATEGORYS, editable=False)
    createdat = models.DateTimeField(u'创建于', auto_now_add=True, help_text=u'系统自动生成')
    createdby = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'创建人', help_text=u'根据当前登录账号，系统自动生成', editable=False, on_delete=models.DO_NOTHING)
    department = models.ForeignKey('org.department', verbose_name=u'适用部门', blank=True, null=True, help_text=u'不设置部门则视为适用所有部门。', on_delete=models.SET_NULL)
    updatedat = models.DateTimeField(u'更新于', auto_now=True, help_text=u'系统自动生成')

    subject = models.CharField(u'标题', max_length=100, help_text=u'少于100字')
    summary = models.CharField(u'内容摘要', max_length=255, blank=True, null=True, help_text=u'少于255字')

    read_count = models.IntegerField(u'阅读次数', default=0, editable=False, help_text=u'显示展示调用的次数')
    publishdate = models.DateTimeField(u'发布时间', blank=True, null=True)
    published = models.BooleanField(u'是否发布', default=False, help_text=u'只有正式发布的内容才能在【展板盒子】上展示。')

    auditstatus = models.CharField(u'审核状态', max_length=1, default='Y', choices=AUDITS, help_text=u'只有审核后的内容才能在【展板盒子】上展示。')
    # auditor = models.ForeignKey('org.police', verbose_name=u'审核人', blank=True, null=True, related_name='audit_news', help_text=u'系统自动设置为当前用户')
    # auditdate = models.DateTimeField( u'审核时间', blank=True, null=True, help_text=u'系统自动生成，当前审核操作的时间')
    memo = models.CharField(u'备注', max_length=200, blank=True, null=True)

    aimboxs = models.ManyToManyField("asset.BoardBox", blank=True, verbose_name=u'发布到盒子', help_text=u'应用于全部展板，不用设置。')

    def clean(self):
        if self.published and self.publishdate is None:
            self.publishdate = datetime.now()

    def __unicode__(self):
        return self.subject

    def __str__(self):
        return self.subject

    def get_department_name(self):
        if self.department:
            return u"%s" % self.department
        else:
            return None

    def get_user_name(self):
        return u"%s" % (self.createdby.username or self.createdby.last_name)


    class Meta:
        verbose_name_plural = verbose_name = u'媒体内容'

    def save(self, *args, **kwargs):
        super(Content, self).save(*args, **kwargs)


class HowToGo(models.Model):
    department = models.ForeignKey('org.department', verbose_name=u'部门', blank=True, null=True, help_text=u'不设置部门则视为适用所有部门。', on_delete=models.SET_NULL)
    title = models.CharField(u'标题', max_length=64, help_text=u"当前区域或楼层名称标题")
    image = models.ImageField(u'引导图片', max_length=200, upload_to='content/howtogo/',  help_text=u"上传当前区域或楼层的引导图,建议图片大于1920x1080。")
    order = models.PositiveSmallIntegerField(u"序号", default=0, help_text=u"排序序号")
    aimboxs = models.ManyToManyField("asset.BoardBox", blank=True, verbose_name=u'发布到展板盒子', help_text=u'应用于全部展板，不用设置。')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = verbose_name = u'办公区域引导'

    def save(self, *args, **kwargs):
        super(HowToGo, self).save(*args, **kwargs)

class News(Content):
    objects = ContentManager()
    picture1 = models.ImageField(u'图片1', upload_to='content/news/%Y/%m/',  blank=True, null=True, help_text=u'')
    picture2 = models.ImageField(u'图片2', upload_to='content/news/%Y/%m/', blank=True, null=True, help_text=u'')
    picture3 = models.ImageField(u'图片3', upload_to='content/news/%Y/%m/', blank=True, null=True, help_text=u'')

    is_head = models.BooleanField(u'头条', default=False, help_text=u'新闻资讯类内容，设置为头条资讯。')
    author = models.CharField(u'作者', max_length=25, blank=True, null=True, help_text='默认填写当前登录人员。')
    ref = models.CharField(u'来源', max_length=50, blank=True, null=True)
    ref_url = models.URLField(u'来源地址', max_length=50, blank=True, null=True,)
    content = models.TextField(u'内容')

    def _has_pic(self):
        return bool(self.picture0 or self.picture1 or self.picture2)
    has_pic = property(_has_pic)

    def clean(self):
        self.category = Content.CAT_NEWS
        super(News, self).clean()

    class Meta:
        # permissions = (("audit_news", u"允许审核公众新闻资讯"),("publish_news", u"允许发布公众新闻资讯"))
        verbose_name_plural = verbose_name = u'新闻资讯'

    def save(self, *args, **kwargs):
        self.category = Content.CAT_NEWS
        super(News, self).save(*args, **kwargs)


class Notice(Content):
    objects = ContentManager()
    author = models.CharField(u'作者', max_length=25, blank=True, null=True, help_text='默认填写当前登录人员。')
    ref = models.CharField(u'来源', max_length=50, blank=True, null=True)
    content = models.TextField(u'内容')

    def clean(self):
        self.category = Content.CAT_NOTICE
        super(Notice, self).clean()

    class Meta:
        # permissions = (("audit_news", u"允许审核公众新闻资讯"),("publish_news", u"允许发布公众新闻资讯"))
        verbose_name_plural = verbose_name = u'通知发布'

    def save(self, *args, **kwargs):
        self.category = Content.CAT_NOTICE
        super(Notice, self).save(*args, **kwargs)


class Notify(Content):
    objects = ContentManager()
    author = models.CharField(u'作者', max_length=25, blank=True, null=True, help_text='默认填写当前登录民警。')
    ref = models.CharField(u'来源', max_length=50, blank=True, null=True)
    content = models.TextField(u'内容')

    def clean(self):
        self.category = Content.CAT_NOTIFY
        super(Notify, self).clean()

    class Meta:
        # permissions = (("audit_news", u"允许审核公众新闻资讯"),("publish_news", u"允许发布公众新闻资讯"))
        verbose_name_plural = verbose_name = u'公告频道'

    def save(self, *args, **kwargs):
        self.category = Content.CAT_NOTIFY
        super(Notify, self).save(*args, **kwargs)


class OfficeDoc(Content):
    objects = ContentManager()
    is_redhead = models.BooleanField(u'红头', default=False, help_text=u'是否对内容套红')
    redhead_title = models.CharField(u'红头标题', max_length=50, blank=True, null=True)
    redhead_no = models.CharField(u'红头文号', max_length=20, blank=True, null=True)
    content = models.TextField(u'内容')

    def clean(self):
        self.category = Content.CAT_OFFICE
        super(OfficeDoc, self).clean()

    class Meta:
        # permissions = (("audit_news", u"允许审核公众新闻资讯"),("publish_news", u"允许发布公众新闻资讯"))
        verbose_name_plural = verbose_name = u'行政公文'

    def save(self, *args, **kwargs):
        self.category = Content.CAT_OFFICE
        super(OfficeDoc, self).save(*args, **kwargs)


class Video(Content):
    objects = ContentManager()
    file = models.FileField(u'视频文件', upload_to='content/video/%Y/%m/', blank=True, null=True, help_text=u'推荐到首页的时候显示在幻灯片中间的照片')
    image = models.ImageField(u'视频图片', upload_to='content/video/%Y/%m/',  blank=True, null=True, help_text=u'给视频上传一张图片')
    order = models.PositiveIntegerField(u'顺序号', default=0)

    enable = models.BooleanField(u'有效', default=True, help_text=u'是否停止视频播放')

    def __unicode__(self):
        return self.subject

    def __str__(self):
        return self.subject

    def clean(self):
        self.category = Content.CAT_VIDEO
        super(Video, self).clean()

    class Meta:
        verbose_name_plural = verbose_name = u'视频频道'

    def save(self, *args, **kwargs):
        self.category = Content.CAT_VIDEO
        super(Video, self).save(*args, **kwargs)


class Picture(Content):
    objects = ContentManager()
    image = models.ImageField(u'主图', upload_to='content/picture/%Y/%m/', blank=True, null=True, help_text=u'默认图片与此图片至少需要设置一张，图片的分辨率最好与设备显示分辨率匹配。')
    order = models.PositiveIntegerField(u'顺序号', default=0, help_text=u'以此顺序号播放图片，没有设置或顺序号相同则以创建时间倒序播放')
    enable = models.BooleanField(u'有效', default=True, help_text=u'是否在展板盒子上显示此张图片。')

    def __unicode__(self):
        return self.subject

    def __str__(self):
        return self.subject

    def clean(self):
        self.category = Content.CAT_PICTURE
        super(Picture, self).clean()

    class Meta:
        verbose_name_plural = verbose_name = u'图片说'

    def save(self, *args, **kwargs):
        self.category = Content.CAT_PICTURE
        super(Picture, self).save(*args, **kwargs)


class SubPicture(models.Model):
    main = models.ForeignKey(Picture, verbose_name="主图", related_name='subpictures', on_delete=models.CASCADE,)
    image = models.ImageField(u'图片', upload_to='content/subpicture/%Y/%m/', blank=True, null=True, help_text=u'默认图片与此图片至少需要设置一张，图片的分辨率最好与设备显示分辨率匹配。')
    text = models.TextField(u"描述",null=True, blank=True, help_text=u"给当前图片说点什么")

    def __str__(self):
        return u"图片 %s" % self.id

    class Meta:
        verbose_name_plural = verbose_name = u'子图片'


class ThirdParty(Content):
   
    image = models.ImageField(u'封面图片', upload_to='content/thirdparty/%Y/%m/', blank=True, null=True, help_text=u'用于列表显示')
    url = models.URLField("URL", max_length=200, help_text=u'第三方内容服务地址')
    token = models.CharField("认证令牌", max_length=50, blank=True, null=True, help_text=u'无需认证请忽略')

    class Meta:
        verbose_name = verbose_name_plural = "第三方内容"

    def __str__(self):
        return self.subject

    # def get_absolute_url(self):
    #     return reverse("ThirdParty_detail", kwargs={"pk": self.pk})

    def save(self, *args, **kwargs):
        self.category = Content.CAT_3P
        super(ThirdParty, self).save(*args, **kwargs)


@receiver(m2m_changed, sender=Content.aimboxs.through)  # m2m_changed: 只有 m2m 字段改变才会触发
@receiver(m2m_changed, sender=HowToGo.aimboxs.through)
def auto_push_m2m_change_info(sender, instance, action, pk_set, **kwargs):
    p = urlparse(NOTIFY_BROKER)
    host, port = p.netloc.split(":")
    topic = "edboard/content/%s" % instance.__class__.__name__.lower()
    # if action == "post_add":
    msg = json.dumps(list(pk_set), ensure_ascii=False)
    publish.single(topic, msg, hostname=host, port=int(port))
    # elif action == "pre_remove" or action == "pre_clear":
    #     pass


@receiver(post_save, sender=News)
@receiver(post_save, sender=Notice)
@receiver(post_save, sender=Notify)
@receiver(post_save, sender=OfficeDoc)
@receiver(post_save, sender=Video)
@receiver(post_save, sender=Picture)
@receiver(post_save, sender=ThirdParty)
@receiver(post_save, sender=HowToGo)
def auto_push_change_info(sender, instance, **kwargs):
    p = urlparse(NOTIFY_BROKER)
    host, port = p.netloc.split(":")
    pk_list = [box.pk for box in instance.aimboxs.all()]
    topic = "edboard/content/%s" % instance.__class__.__name__.lower()
    # topic = "mr7b/ind/edboard/info/053096912362"
    msg = json.dumps(pk_list, ensure_ascii=False)
    # msg = ''
    publish.single(topic, msg, hostname=host, port=int(port))
